package com.bmft.jingdong.util.es;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.bmft.jingdong.constant.IndexConst;
import com.bmft.jingdong.pojo.GoodContent;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingDeque;

/**
 * 这里封装ES基本方法.
 * goods 的名称就是id,防止名称重复.（但是我们这里的书本的数量不够，我们向把id删除）
 * @author Jarvan
 * @version 1.0
 * @create 2020/11/11 18:51
 */
@Component
@Log4j2
public class ElasticSearchApi {
    @Autowired
    @Qualifier("restHighLevelClient")
    RestHighLevelClient restHighLevelClient;
    public boolean addList(List<GoodContent> goodContentList) throws IOException {
        log.info("=============进入 ES API add 添加============");

        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2s");
        //填入数据

        for (GoodContent goodContent : goodContentList) {
            bulkRequest.add(new IndexRequest(IndexConst.INDEX_CONST)
                    .source(JSON.toJSONString(goodContent),  XContentType.JSON)

            );

        }
        //发送请求
        BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        return bulk.status()== RestStatus.OK;
    }
    public List<Map<String, Object>> getList(String SearchKey, int from ,int  size) throws IOException {
        log.info("========进入 ES  API get 查询:"+SearchKey+"=============");
        SearchRequest searchRequest = new SearchRequest(IndexConst.INDEX_CONST);
        //【重点】构建searchSourcesBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建查询
        searchSourceBuilder.query(QueryBuilders.matchQuery("name",SearchKey));
        //翻页
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);
        //timeout
        searchSourceBuilder.timeout();
        //【将builder放入request中】
        searchRequest.source(searchSourceBuilder);
        //【高亮1.】
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        //多个高亮字段
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        //将高亮设置到search builder中
        searchSourceBuilder.highlighter(highlightBuilder);

        //【搜索】
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        ArrayList<Map<String, Object>> arrayList = new ArrayList<>();
        //【高亮2.解析高亮】将高亮的name替换掉原来的name即可
        for (SearchHit hit : hits) {
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
//            hit.getSourceAsMap() 就是原来的结果
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if (name !=null){
                Text[] fragments = name.fragments();
                String newName = "";
                for (Text fragment : fragments) {
                    newName += fragment;
                }
                //将sourcesMap中的值替换.
                sourceAsMap.put("name",newName);
            }
            arrayList.add(sourceAsMap);
        }
        return arrayList;
    }
}
